package fr.emse.tatiana.scoresheetvisualisation;

import java.util.List;
import java.util.Vector;

import org.eclipse.draw2d.ConnectionLayer;
import org.eclipse.draw2d.FreeformLayer;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.AbstractEditPart;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

import fr.emse.tatiana.replayable.IReplayableModel;

public class ReplayableModelPart extends AbstractGraphicalEditPart {

	protected IReplayableModel replayablemodel;
	protected double xzoom;
	protected Viewport viewport;
	protected long duration;
	
	public ReplayableModelPart(IReplayableModel model) {
		super();
		setModel(model);
		this.replayablemodel = model;
		xzoom = 1.0;
	}

	@Override
	protected IFigure createFigure() {
		IFigure ret = new FreeformLayer();
		ConnectionLayer connLayer = (ConnectionLayer)getLayer(LayerConstants.CONNECTION_LAYER);
		ShortestPathConnectionRouter router = new ShortestPathConnectionRouter(ret);

		connLayer.setConnectionRouter(router);
		return ret;
	}

	@Override
	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, null);
		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
	 */
	@Override
	protected List<Object> getModelChildren() {
		List<Object> l = new Vector<Object>();
		for (int i=0; i<replayablemodel.getEventCount(); i++) {
			l.add(replayablemodel.getEvent(i));
		}
		return l;
	}

	public void expandToContain(Rectangle bounds) {
		// TODO Auto-generated method stub
		
	}

	public void setXZoom(double d) {
		double oldzoom = xzoom;
		Point p1 = viewport.getClientArea().getCenter();
		Point p2 = p1.getCopy();
		Point p = viewport.getViewLocation();
		xzoom = d;
		this.refreshVisuals();
		viewport.validate();
		p2.scale(xzoom/ oldzoom);
		Dimension dif = p2.getDifference(p1);
		p.x += dif.width;
		viewport.setViewLocation(p);
	}
	
	public double getXZoom() {
		return xzoom;
	}
	
    public int millisToCoord(long fromfirst) {
    	if (duration < 30*1000*1000) {
    		return (int) (Math.round((fromfirst*xzoom)/1000));
    	} else {
    		double adjust = duration / (30*1000);
    		return (int) (Math.round((fromfirst*xzoom)/adjust));
    	}
    }
    
    @Override
	protected void refreshVisuals() {
		long first = replayablemodel.getFirstTime();
        long last = replayablemodel.getLastTime();
        duration = (last-first);
//TODO use layout manager or something else.
		getFigure().setBounds(new Rectangle(0,0,millisToCoord(duration)+50,300));
		List<AbstractEditPart> children = this.getChildren();
		for (AbstractEditPart child: children) {
			child.refresh();
		}
    }

	public void zoomIn() {
		setXZoom(xzoom*1.5);
	}

	public void zoomOut() {
		setXZoom(xzoom/1.5);
		
	}

	public void setViewPort(Viewport figure) {
		this.viewport = figure;
		
	}

}
